#!/usr/bin/python

from hips import appengine_unittest
import datetime
import unittest

from google.appengine.api import users
from google.appengine.ext import db

from hips import datastore
from hips import datastore_mocks
from hips import serialization


class SerializationTestCase(appengine_unittest.AppEngineTest):
  """Tests that models round-trip properly through serialization."""

  def assertModelsEqual(self, expected, actual):
    properties = expected.properties()
    self.assertEquals(expected.__class__, actual.__class__)
    self.assertEquals(len(properties.values()),
        len(actual.properties().values()))
    for prop in properties.values():
      expected_value = prop.__get__(expected, expected.__class__)
      actual_value = prop.__get__(actual, actual.__class__)
      # TODO Compare model trees too?
      if isinstance(expected_value, db.Model):
        expected_value = expected_value.key()
      if isinstance(actual_value, db.Model):
        actual_value = actual_value.key()
      self.assertEquals(expected_value, actual_value,
          msg=("Mismatch on property: %s\nexpected: %s\nactual: %s" %
              (prop.name, str(expected_value), str(actual_value))))

  def assertModelRoundTrip(self, model):
    model.put()
    serialized = serialization.WriteModelToString(model)
    self.assertTrue(serialized)  # Just make sure it's not empty
    deserialized = serialization.ReadModelListFromString(serialized)
    self.assertModelsEqual(model, deserialized[0])

  def testInstitution(self):
    model = datastore_mocks.CreateInstitution()
    self.assertModelRoundTrip(model)

  def testDoctor(self):
    model = datastore_mocks.CreateDoctor()
    self.assertModelRoundTrip(model)

  def testSchedule(self):
    model = datastore_mocks.CreateSchedule()
    self.assertModelRoundTrip(model)

  def testDoctorConstraint(self):
    model = datastore_mocks.CreateDoctorConstraint()
    self.assertModelRoundTrip(model)

  def testScheduleBlock(self):
    model = datastore_mocks.CreateScheduleBlock()
    self.assertModelRoundTrip(model)

  def testScheduleSolution(self):
    model = datastore_mocks.CreateScheduleBlock()
    self.assertModelRoundTrip(model)

  def testScheduleSolutionBlock(self):
    model = datastore_mocks.CreateScheduleSolutionBlock()
    self.assertModelRoundTrip(model)


if __name__ == '__main__':
  unittest.main()
